import * as React from "react";
import type {ClassInstance} from "./interface.ts";
import {StateCore} from "./StateCore.ts";
import {useIsInComponent} from "./functions.ts";

export {state} from "./decorators/state.ts";
export {initialize} from './decorators/Initialize.ts'
export {builder} from './decorators/builder.ts'
export {modal} from './decorators/modal.tsx'

export function createHook<T>(instance: ClassInstance<T>): () => T {
	return function (): T {
		if (!useIsInComponent()) return instance as unknown as T;

		const usedStates = React.useRef(new Set<string>()).current; // 跨渲染持久化
		const [, forceUpdate] = React.useState({});
		React.useEffect(() => {
			const subscriptions: (() => void)[] = [];
			for (const key of instance.__states.keys()) {
				const state = instance.__states.get(key)!
				const unsubscribe = state.subscribe(() => {
					if (usedStates.has(key)) {
						forceUpdate({});
					}
				});
				subscriptions.push(unsubscribe);
			}

			return () => {
				subscriptions.forEach(unsubscribe => unsubscribe());
			};
		}, [usedStates]);

		const proxy = new Proxy(instance, {
			get(target, prop) {
				if (instance.__states.has(prop as string)) {
					usedStates.add(prop as string); // 记录依赖
				}
				return Reflect.get(target, prop);
			},
		});

		return proxy as unknown as T;
	}
}

/**
 * 创建一个带有状态管理和React组件生命周期功能的类实例工厂函数
 *
 * @template T
 * @param {new () => T} StoreClass - 一个无参构造函数，用于创建类的实例
 * @returns {() => T} - 返回一个函数，该函数在调用时会返回一个具有状态管理和React组件生命周期功能的类实例
 */
export function create<T extends object>(StoreClass: new () => T): () => T {
	// 创建类的实例，并将其类型断言为ClassInstance<T>
	const instance = (new StoreClass()) as ClassInstance<T>;

	// 将instance绑定到所有的方法
	const prototype = Object.getPrototypeOf(instance);
	const methods = Object.getOwnPropertyNames(prototype)
		.filter(name => name !== 'constructor' && typeof prototype[name] === 'function');

	methods.forEach(methodName => {
		instance[methodName] = prototype[methodName].bind(instance);
	});

	// 为所有的状态添加getter和setter，以便实现响应式
	if(instance.__states){
		for (const key of instance.__states.keys()) {
			const state = new StateCore(instance[key])
			Object.defineProperty(instance, key, {
				get: () => state.value,
				set: (v: any) => state.value = v,
				enumerable: true,
				configurable: true
			})
			instance.__states.set(key, state);
		}
	}

	// 返回一个工厂函数，用于创建具有状态管理和React组件生命周期功能的类实例
	return createHook(instance);
}
